home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 1.iso
/
ARGONET
/
PD
/
GRAPHICS
/
GIF2RPC.SPK
/
source
/
16bpp_66bit
/
c
/
dither2x2
< prev
next >
Wrap
Text File
|
1995-10-16
|
5KB
|
183 lines
/* dither2x2.c
* AUTHOR: Cy Booker, cy@cheepnis.demon.co.uk
* LICENSE: FreeWare, Copyright (c) 1995 Cy Booker
*/
#include "internal.h"
#include <assert.h>
#include <string.h> /* memset() */
#include "OS:macros.h"
#include "OS:hourglass.h"
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
static void calculate_dither2x2(
int dither[2][2],
os_colour colour);
static bits map_palette_entry_to_16bpp_colour(
os_colour colour);
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
extern bool process_gif_16bpp_dither2x2_66bit(
const process_gif *p) {
byte *rove;
bits dest;
int width, height;
int x, y;
const os_colour *palette;
int line_length;
int index;
int dither[256][2][2];
assert(p);
assert(p->pixel_width > 0);
assert(p->pixel_height > 0);
assert(p->in_palette.colours);
/*
* pre-calculate dither table
* to save a function call in middle loop
* thus the compiler has more registers to play with
*/
palette = p->in_palette.colours;
for (index= p->in_palette.ncolours; (index > 0); ) {
index--;
calculate_dither2x2(dither[index], palette[index]);
}
/*
* not we pre-load values from the process_gif array
* because it considerably helps the compiler produce better code
*/
rove = p->buffer;
width = (p->pixel_width + 1) & ~1;
height = p->pixel_height;
line_length = p->line_length;
for (y= height; (y > 0); y--) {
if ((y & 7) == 0) {
xhourglass_percentage((y * 100) / height);
}
for (x= width - 1; (x >= 0); x--) {
assert((x & 1) == 1);
/*
* writing one 32-bit word is much faster than two 16-bit shorts
*/
index = rove[x];
dest = dither[index][y & 1][x & 1];
x--;
index = rove[x];
dest <<= 16;
dest |= dither[index][y & 1][x & 1];
*(((int *)rove) + (((unsigned int)x) >> 1)) = dest;
}
rove += line_length;
}
return FALSE;
}
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* strictly speaking, this isn't a 66bit routine!
* but I can't be arsed to recode it so it is, as the 48 bit routines are faster
*/
static void calculate_dither2x2(
int dither[2][2],
os_colour colour) {
int target_r, target_g, target_b;
int r, g, b;
bits tl;
int tl_r, tl_g, tl_b;
bits br;
int br_r, br_g, br_b;
bits tr;
int tr_r, tr_g, tr_b;
bits bl;
/*
* we now use ``colourtrans'' dithering algorithm, where X is the
* destination colour, and all values are (r, g, b) tuples
* topleft <-- X
* bottomright <-- X - (topleft - X)
* topright <-- X - (((topleft - X) + (bottomright - X)) / 2)
* bottomleft <-- X - (((topleft - X) + (bottomright - X) + (topright - X)) / 3)
*
* personally, I don't see why the need for divisions, as surely we are using:
* "OK we missed X by N, therefore compensate by choosing X - N"
* but colourtrans is doing
* missed by TL and missed by BR, therefore try X - ((TL+TR)/2)
*
* humph, it works, anyway
*/
target_r = 31 * ((colour >> 8) & 0xff);
target_g = 31 * ((colour >> 16) & 0xff);
target_b = 31 * ((colour >> 24) & 0xff);
tl = map_palette_entry_to_16bpp_colour(colour);
tl_r = 255 * ((tl >> 0) & 0x1f);
r = MAX((2 * target_r) - tl_r, 0) / 31;
r = MIN(255, r);
tl_g = 255 * ((tl >> 5) & 0x1f);
g = MAX((2 * target_g) - tl_g, 0) / 31;
g = MIN(255, g);
tl_b = 255 * ((tl >> 10) & 0x1f);
b = MAX((2 * target_b) - tl_b, 0) / 31;
b = MIN(255, b);
br = map_palette_entry_to_16bpp_colour((r << 8) | (g << 16) | (b << 24));
br_r = 255 * ((br >> 0) & 0x1f);
r = MAX((2 * 2 * target_r) - (tl_r + br_r), 0) / (2*31);
r = MIN(255, r);
br_g = 255 * ((br >> 5) & 0x1f);
g = MAX((2 * 2 * target_g) - (tl_g + br_g), 0) / (2*31);
g = MIN(255, g);
br_b = 255 * ((br >> 10) & 0x1f);
b = MAX((2 * 2 * target_b) - (tl_b + br_r), 0) / (2*31);
b = MIN(255, b);
tr = map_palette_entry_to_16bpp_colour((r << 8) | (g << 16) | (b << 24));
tr_r = 255 * ((tr >> 0) & 0x1f);
r = MAX((3 * 2 * target_r) - (tl_r + br_r + tr_r), 0) / (3*31);
r = MIN(255, r);
tr_g = 255 * ((tr >> 5) & 0x1f);
g = MAX((3 * 2 * target_g) - (tl_g + br_g + tr_g), 0) / (3*31);
g = MIN(255, g);
tr_b = 255 * ((tr >> 10) & 0x1f);
b = MAX((3 * 2 * target_b) - (tl_b + br_r + tr_b), 0) / (3*31);
b = MIN(255, b);
bl = map_palette_entry_to_16bpp_colour((r << 8) | (g << 16) | (b << 24));
dither[0][0] = tl;
dither[0][1] = tr;
dither[1][0] = bl;
dither[1][1] = br;
}
static bits map_palette_entry_to_16bpp_colour(
os_colour colour) {
int red, grn, blu;
red = ((colour << (2*8)) >> 24) & 0xff; red = ((red * 0x1f) + 0x80) >> 8;
grn = ((colour << (1*8)) >> 24) & 0xff; grn = ((grn * 0x1f) + 0x80) >> 8;
blu = ((colour << (0*8)) >> 24) & 0xff; blu = ((blu * 0x1f) + 0x80) >> 8;
return red | (grn << 5) | (blu << 10);
}